package cn.xinfei.xdecision.data.core.migrate;


import cn.hutool.core.collection.CollectionUtil;
import cn.xinfei.xdecision.common.migrate.ElementMapper;
import cn.xinfei.xdecision.common.model.datax.enums.MigrateEnum;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataException;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataExceptionType;
import cn.xinfei.xdecision.common.model.datax.migrate.Element;
import cn.xinfei.xdecision.data.core.vo.migrate.MigrateVarReqVO;
import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MigrateVarJob {

    @Resource
    ElementMapper elementMapper;
    @Resource
    MigrateVarService migrateVarService;


    @XxlJob(value = "migrateVars")
    public ReturnT<String> migrateVars(String param) {
        long startTime = System.currentTimeMillis();
        MigrateParam migrateParam = JSONObject.parseObject(param, MigrateParam.class);
        String migrateEnumParam = migrateParam.getMigrateEnum();
        MigrateVarReqVO migrateVarReqVO = migrateParam.getMigrateVarReqVO();
        XxlJobLogger.log("start migrate...{}",
                JSONObject.toJSONString(migrateEnumParam));

        List<Element> javaVars = elementMapper.getAllElesBySystem("java");
        List<Element> pythonVars = elementMapper.getAllElesBySystem("python");
        List<Element> modelCacheVars = elementMapper.getAllModelCacheElements();


        Map<String, List<Element>> fromPythonElesMap = pythonVars.stream().collect(Collectors.groupingBy(Element::getFrom));
        List<Element> pythonFuncVars = fromPythonElesMap.get("function");
        List<Element> pythonInputVars = fromPythonElesMap.get("input");
        List<Element> pythonOutputVars = fromPythonElesMap.get("output");
        List<Element> pythonInnerVars = fromPythonElesMap.get("ruleset");


        Map<String, List<Element>> fromJavaElesMap = javaVars.stream().collect(Collectors.groupingBy(Element::getFrom));
        List<Element> javaFuncAndComboVars = (List<Element>) CollectionUtil.union(fromJavaElesMap.get("function"), fromJavaElesMap.get("combo"));
        List<Element> javaFuncVars = fromJavaElesMap.get("function");
        List<Element> javaInputVars = fromJavaElesMap.get("input");
        List<Element> javaOutputVars = fromJavaElesMap.get("output");
        List<Element> javaInnerVars = fromJavaElesMap.get("ruleset");

        List<List<String>> pythonThirdPartyVars = migrateVarService.getPythonThirdPartyVars();
        List<List<String>> pythonThirdPartyCacheVars = migrateVarService.getPythonThirdPartyCacheVars();
        List<List<String>> pythonBizVars = migrateVarService.getPythonBizVars();

        try {
            MigrateEnum migrateEnum = MigrateEnum.fromName(migrateEnumParam);
            switch (migrateEnum) {
                case JAVA_BIZ:
                    List<String> allJavaBizVarCode = migrateVarService.getAllJavaBizVarCode(javaFuncAndComboVars);
                    migrateVarService.migrateJavaBizVars(javaFuncVars, allJavaBizVarCode, migrateVarReqVO);
                    log.info("migrate java_biz vars success!");
                    break;
                case JAVA_BASIC:
                    migrateVarService.migrateJavaBasicVars(javaInputVars, javaOutputVars, javaInnerVars, migrateVarReqVO);
                    log.info("migrate java_basic vars success!");
                    break;
                case JAVA_THIRDPARTY:
                    migrateVarService.migrateJavaThirdPartyVars(javaFuncVars, migrateVarReqVO);
                    log.info("migrate java_thridparty vars success!");
                    break;
                case PYTHON_BIZ:
                    migrateVarService.migratePythonBizVars(pythonFuncVars, pythonBizVars, migrateVarReqVO);
                    log.info("migrate python_biz vars success!");
                    break;
                case PYTHON_BASIC:
                    migrateVarService.migratePythonBasicVars(pythonInputVars, pythonOutputVars, pythonInnerVars, migrateVarReqVO);
                    log.info("migrate python_basic vars success!");
                    break;
                case PYTHON_THIRDPARTY:
                    migrateVarService.migratePythonThirdPartyVars(pythonFuncVars, pythonThirdPartyVars, migrateVarReqVO);
                    log.info("migrate python_thridparty vars success!");
                    break;
                case PYTHON_THIRDPARTY_CACHE:
                    migrateVarService.migratePythonThirdPartyVars(pythonFuncVars, pythonThirdPartyCacheVars, migrateVarReqVO);
                    log.info("migrate python_thridparty_cache vars success!");
                    break;
                case VAR_PARAM:
                    migrateVarService.migrateVarParams();
                    log.info("migrate varParams success!");
                    break;
                case PYTHON_MODEL_CACHE:
                    migrateVarService.migratePythonModelVars(modelCacheVars, migrateVarReqVO);
                    log.info("migrate python_model_cache vars success!");
                    break;
                case PYTHON_MODEL:
                    migrateVarService.migratePythonModelVars(pythonFuncVars, migrateVarReqVO);
                    log.info("migrate python_model vars success!");
                    break;
                default:
                    throw new XDecisionDataException(XDecisionDataExceptionType.DATA_NO_SUCH_MIGRATE_TYPE_ERROR);
            }

        } catch (Exception e) {
            XxlJobLogger.log("error in migrateParam: " + param + "for: " + e.getMessage());
            return ReturnT.FAIL;
        }
        long endTime = System.currentTimeMillis();
        XxlJobLogger.log("stop migrateParam ={}...timeConsuming ={}",
                param, endTime - startTime);
//        XxlJobHelper.handleSuccess("migrateParam ={}" + param + " 执行成功！");
        return ReturnT.SUCCESS;
    }

    @Data
    public static class MigrateParam {
        private String migrateEnum;
        private MigrateVarReqVO migrateVarReqVO;
    }


}
